package com.hope.bubble.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hope.bubble.mapper.BubbleTagMapper;
import com.hope.bubble.mapper.BubbleTopicMapper;
import com.hope.bubble.mapper.UmsUserMapper;
import com.hope.bubble.model.dto.CreateTopicDTO;
import com.hope.bubble.model.entity.BubblePost;
import com.hope.bubble.model.entity.BubbleTag;
import com.hope.bubble.model.entity.BubbleTopicTag;
import com.hope.bubble.model.entity.UmsUser;
import com.hope.bubble.model.vo.PostVO;
import com.hope.bubble.model.vo.ProfileVO;
import com.hope.bubble.service.IBubblePostService;
import com.hope.bubble.service.IBubbleTagService;
import com.hope.bubble.service.IBubbleTopicTagService;
import com.hope.bubble.service.IUmsUserService;
import com.vdurmont.emoji.EmojiParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 文件名：BubblePostServiceImpl
 * 创建者：hope
 * 邮箱：1602774287@qq.com
 * 微信：hope4cc
 * 创建时间：2022/10/22-10:08
 * 描述：
 */
@Service
public class BubblePostServiceImpl extends ServiceImpl<BubbleTopicMapper, BubblePost> implements IBubblePostService {
    @Resource
    private BubbleTagMapper bubbleTagMapper;

    @Resource
    private UmsUserMapper umsUserMapper;

    @Resource
    @Lazy
    private IBubbleTagService bubbleTagService;

    @Autowired
    private IBubbleTopicTagService bubbleTopicTagService;

    @Autowired
    private IUmsUserService iUmsUserService;

    @Override
    public Page<PostVO> getList(Page<PostVO> page, String tab) {
        // 查询话题 按照客户端的分页要求 分页 tab(热门,最新)
        Page<PostVO> iPage = this.baseMapper.selectListAndPage(page, tab);
        // 查询话题的标签
        iPage.getRecords().forEach(topic -> {
            //根据帖子的id 拿到标签的集合
            List<BubbleTopicTag> topicTags = bubbleTopicTagService.selectByTopicId(topic.getId());
            if (!topicTags.isEmpty()) { //如果帖子标签不为空
                List<String> tagIds = topicTags.stream().map(BubbleTopicTag::getTagId).collect(Collectors.toList());
                //批处理 返回该帖子的全部标签
                List<BubbleTag> tags = bubbleTagMapper.selectBatchIds(tagIds);
                //把(全部)标签 保存到帖子中
                topic.setTags(tags);
            }
        });
        return iPage;
    }


    /**
     *
     * @param dto
     * @param user
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class) //事务处理 涉及多表操作,保证多个表操作要么全部成功,失败回滚
    public BubblePost create(CreateTopicDTO dto, UmsUser user) {
        //使用mybatisplus提供的查询单条数据 selectOne
        //查询 帖子标题是否存在,是否有同样的标题存在,如果存在抛出异常
        BubblePost topic1 = this.baseMapper.selectOne(new LambdaQueryWrapper<BubblePost>().eq(BubblePost::getTitle, dto.getTitle()));
        Assert.isNull(topic1, "话题已存在，请修改");

        //没有的情况下,创建新的帖子
        // 封装 把帖子插入帖子信息表
        BubblePost topic = BubblePost.builder()
                .userId(user.getId()) //发帖人id
                .title(dto.getTitle())  //前端输入的帖子标题
                .content(EmojiParser.parseToAliases(dto.getContent())) //帖子内容
                .createTime(new Date()) //发帖子时间
                .build();
        this.baseMapper.insert(topic); //然后把帖子插入数据库

        // 用户积分增加
        int newScore = user.getScore() + 1;//用户表 积分字段 积分加一
        umsUserMapper.updateById(user.setScore(newScore)); //更新用户表

        // 标签
        if (!ObjectUtils.isEmpty(dto.getTags())) { //前端已经保证了标签至少为1个, 不过为了数据,还是再校验
            // 保存标签 把前端输入的标签保存插入数据库
            List<BubbleTag> tags = bubbleTagService.insertTags(dto.getTags());
            // 处理标签与话题的关联  得到返回的标签列表,存放到 topictag 的服务中
            bubbleTopicTagService.createTopicTag(topic.getId(), tags);
        }

        return topic;
    }

    @Override
    public Map<String, Object> viewTopic(String id) {
        //初始化map
        Map<String, Object> map = new HashMap<>(16);
        //根据客户端传过来的帖子id 找到数据库中的帖子
        BubblePost topic = this.baseMapper.selectById(id);
        //如果为空,抛出异常
        Assert.notNull(topic, "当前话题不存在,或已被作者删除");
        // 查询话题详情  View字段(浏览次数) 用户访问一次加1
        topic.setView(topic.getView() + 1);
        this.baseMapper.updateById(topic);
        // emoji转码
        topic.setContent(EmojiParser.parseToUnicode(topic.getContent()));
        map.put("topic", topic);
        // 标签
        QueryWrapper<BubbleTopicTag> wrapper = new QueryWrapper<>();
        //查找帖子关联的标签
        wrapper.lambda().eq(BubbleTopicTag::getTopicId, topic.getId());
        //初始化set 把标签存入set ,set可以保证标签的唯一性
        Set<String> set = new HashSet<>();
        //根据帖子id 找到跟帖子关联的所有的标签对象
        for (BubbleTopicTag articleTag : bubbleTopicTagService.list(wrapper)) {
            //得到每个标签的id
            set.add(articleTag.getTagId());
        }
        //set 中是标签表的id集合 相当于使用sql 语句中 in 查找相关的id
        //得到标签对象集合
        List<BubbleTag> tags = bubbleTagService.listByIds(set);
        //,把标签对象方法哦map 返回回去
        map.put("tags", tags);

        //根据 topic.getUserId() 帖子的用户id  得到用户的id
        //调用 iUmsUserService.getUserProfile 得到用户的全部信息
        ProfileVO user = iUmsUserService.getUserProfile(topic.getUserId());
        map.put("user", user);

        return map;
    }
}

